package org.farec.tcc.dao;

import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.List;

import org.farec.tcc.interfaces.OcorrenciaInterface;
import org.farec.tcc.modelo.Ocorrencia;
import org.farec.tcc.modelo.Ocorrencia_Historico;
import org.farec.tcc.modelo.Usuario;

public class IncidenteDAO implements OcorrenciaInterface{

	private Connection connection;
	
	public IncidenteDAO(Connection connection)
	{
		this.connection = connection;
	}
	
	@Override
	public void adiciona(Ocorrencia ocorrencia) {
		// TODO Auto-generated method stub
		String sql = "INSERT INTO incidente(area, categoria, descricao, unidade, cliente, operador,local, status, dataabertura, prioridade)" +
				 	 " VALUES (?,?,?,?,?,?,?,?,?,?)";
		try
		{	
			//Prepara o statement para insercao
			PreparedStatement stmt = connection.prepareStatement(sql);
			
			//seta os dados
			stmt.setString(1, ocorrencia.getArea());
			stmt.setString(2, ocorrencia.getCategoria());
			stmt.setString(3, ocorrencia.getDescricao());
			stmt.setString(4, ocorrencia.getUnidade());
			stmt.setString(5, ocorrencia.getCliente());
			stmt.setString(6, ocorrencia.getOperador());
			stmt.setString(7, ocorrencia.getLocal());
			stmt.setString(8, ocorrencia.getStatus());
			stmt.setDate(9, new Date( ocorrencia.getDataAbertura().getTimeInMillis()));
			stmt.setString(10, ocorrencia.getPrioridade());
			
			stmt.execute();
			stmt.close();
			
		}
		catch(SQLException e)
		{
			throw new RuntimeException(e);
		}
	}

	@Override
	public List<Ocorrencia> getLista(Usuario usuario) {
		// TODO Auto-generated method stub
		try
		{
			PreparedStatement stmt = null;
			
			if(usuario.getGrupo().equalsIgnoreCase("ADMINISTRADORES"))
			{
				String sql ="SELECT id,categoria,unidade,local,cliente,operador,dataabertura," +
					    "datafechamento,prioridade,status FROM incidente order by id desc";
				
				stmt = this.connection.prepareStatement(sql);
			}
			
			else
			{
				if(verificaResponsavel(usuario) != 0)
				{
					String sql = "SELECT id,categoria,unidade,local,cliente,operador,dataabertura, datafechamento,prioridade,status FROM incidente " +
							"WHERE area IN("+ 
							   				"SELECT nome from area WHERE responsavel IN("+
							   												  "SELECT t2.nome FROM usuario as t1, responsavel as t2 "+
							   												  "WHERE t1.usuario=? and t1.idresponsavel=t2.id" +
							   												  ")" +
							   ") order by id desc";
					
					stmt = this.connection.prepareStatement(sql);
					stmt.setString(1, usuario.getUsuario());
					
					
				}
				
				else
				{
					String sql ="SELECT id,categoria,unidade,local,cliente,operador,dataabertura," +
							"datafechamento,prioridade,status from incidente WHERE area=? order by id desc";
					
					stmt = this.connection.prepareStatement(sql);
					stmt.setString(1, usuario.getArea());
				}
				
			}
		
			ResultSet rs = stmt.executeQuery();
			List<Ocorrencia> ocorrencias = new ArrayList<Ocorrencia>();
			while(rs.next())
			{
				//Criando um nova instancia
				Ocorrencia ocorrencia = new Ocorrencia();
				ocorrencia.setCodigo(rs.getInt("id"));
				ocorrencia.setCategoria(rs.getString("categoria"));
				ocorrencia.setUnidade(rs.getString("unidade"));
				ocorrencia.setLocal(rs.getString("local"));
				ocorrencia.setCliente(rs.getString("cliente"));
				ocorrencia.setOperador(rs.getString("operador"));
				
				//Montado o Calendar
				Calendar dataAbertura = Calendar.getInstance();
				Calendar dataFechamento = Calendar.getInstance();
				dataAbertura.setTime(rs.getDate("dataabertura"));
				ocorrencia.setDataAbertura(dataAbertura);
				
				if(rs.getDate("datafechamento") != null )
				{
					dataFechamento.setTime(rs.getDate("datafechamento"));
					ocorrencia.setDataFechamento(dataFechamento);
				}
				ocorrencia.setPrioridade(rs.getString("prioridade"));
				ocorrencia.setStatus(rs.getString("status"));
				
				//Adicionando objeto a lista
				ocorrencias.add(ocorrencia);
			}
			
			rs.close();
			stmt.close();
			
			return ocorrencias;
			
		}
		catch(SQLException e)
		{
			throw new RuntimeException(e);
		}
	}

	public int verificaResponsavel(Usuario usuario)
	{
		int codigo=0;
		
		try
		{
			PreparedStatement stmt = this.connection.prepareStatement("SELECT idresponsavel from usuario WHERE usuario=?");
			
			stmt.setString(1, usuario.getUsuario());
			
			ResultSet rs = stmt.executeQuery();
			
			if(rs.next())
			{
				codigo= rs.getInt("idresponsavel");
			}
		}
		
		catch(SQLException e)
		{
			throw new RuntimeException(e);
		}
		
		return codigo;
	}
		
	@Override
	public void altera(Ocorrencia ocorrencia) {
		// TODO Auto-generated method stub
		String sql = "UPDATE incidente SET area=?, categoria=?, descricao=?, unidade=?, " +
				 "local=?, status=?, dataabertura=?, prioridade=? WHERE id=?";
		try
		{
			PreparedStatement stmt = this.connection.prepareStatement(sql);
			
			//seta os dados
			stmt.setString(1, ocorrencia.getArea());
			stmt.setString(2, ocorrencia.getCategoria());
			stmt.setString(3, ocorrencia.getDescricao());
			stmt.setString(4, ocorrencia.getUnidade());
			stmt.setString(5, ocorrencia.getLocal());
			stmt.setString(6, ocorrencia.getStatus());
			stmt.setDate(7, new Date(ocorrencia.getDataAbertura().getTimeInMillis()));
			stmt.setString(8, ocorrencia.getPrioridade());
			stmt.setInt(9, ocorrencia.getCodigo());
			
			stmt.execute();
			stmt.close();
			
			
		}
		
		catch(SQLException e)
		{
			throw new RuntimeException(e);
		}
	}

	@Override
	public void remove(Ocorrencia ocorrencia) {
		// TODO Auto-generated method stub
		try
		{
			PreparedStatement stmt = this.connection.prepareStatement("DELETE from incidente where id=?");
			stmt.setInt(1,ocorrencia.getCodigo());
			stmt.execute();
			stmt.close();
		}
		catch(SQLException e)
		{
			throw new RuntimeException(e);
		}
	}

	@Override
	public Ocorrencia buscaPorCodigo(int id) {
		// TODO Auto-generated method stub
		ResultSet rs;
		Ocorrencia ocorrencia = new Ocorrencia();
		try
		{
			PreparedStatement stmt = this.connection.prepareStatement("select * from incidente where id=?");
			stmt.setInt(1, id);
			rs=stmt.executeQuery();
			
			if(rs.next())
			{
				ocorrencia.setCodigo(rs.getInt("id"));
				ocorrencia.setArea(rs.getString("area"));
				ocorrencia.setCategoria(rs.getString("categoria"));
				ocorrencia.setDescricao(rs.getString("descricao"));
				ocorrencia.setUnidade(rs.getString("unidade"));
				ocorrencia.setCliente(rs.getString("cliente"));
				ocorrencia.setOperador(rs.getString("operador"));
				ocorrencia.setLocal(rs.getString("local"));
				ocorrencia.setStatus(rs.getString("status"));
				ocorrencia.setPrioridade(rs.getString("prioridade"));
				
				//Montado o Calendar
				Calendar data = Calendar.getInstance();
				data.setTime(rs.getDate("dataabertura"));
				ocorrencia.setDataAbertura(data);
			}
			stmt.close();
			rs.close();
			
		}
		
		catch(SQLException e)
		{
			throw new RuntimeException(e);
		}
		return ocorrencia;
	}
	
	public int getQtdAberto(Usuario usuario)
	{
		try
		{
			int qtd=0;
			PreparedStatement stmt = null;

			if(usuario.getGrupo().equalsIgnoreCase("ADMINISTRADORES"))
			{
				String sql ="SELECT count(status) from incidente where status=? GROUP BY status";
				stmt = this.connection.prepareStatement(sql);
				
				stmt.setString(1, "Aberto");
			}
			
			else
			{
				if(verificaResponsavel(usuario) != 0)
				{
					String sql ="SELECT count(status) from incidente where status=? and area IN ("+ 
							   				"SELECT nome from area WHERE responsavel IN("+
							   												  "SELECT t2.nome from usuario as t1, responsavel as t2 "+
							   												  "WHERE t1.usuario=? and t1.idresponsavel=t2.id" +
							   												  ")" +
							   ") GROUP BY status";
					stmt = this.connection.prepareStatement(sql);
					
					stmt.setString(1, "Aberto");
					stmt.setString(2, usuario.getUsuario());
				}
				
				else
				{
					String sql ="SELECT count(status) from incidente where status=? and area=? GROUP BY status";
					stmt = this.connection.prepareStatement(sql);
					
					stmt.setString(1, "Aberto");
					stmt.setString(2, usuario.getArea());
				}
				
			}

			ResultSet rs = stmt.executeQuery();

			if(rs.next())
			{
				qtd = rs.getInt("count");
			}
			
			return qtd;
			
		}
		catch(SQLException e)
		{
			throw new RuntimeException(e);
		}
	}

	//Metodos referentes ao historico da solicitacao
	
	public void adicionaHistorico(Ocorrencia ocorrencia, Ocorrencia_Historico historico)
	{
		String sql = "BEGIN;"
					 +"UPDATE incidente SET status=? where id=?;"
					 +"INSERT INTO incidentehistorico(descricao,usuario,codigoincidente,data) VALUES(?,?,?,?);"
					 +"COMMIT;";
			
		try
		{
			//Prepara o statement para insercao
			PreparedStatement stmt = connection.prepareStatement(sql);
			
			//Insere na tabela solicitacao
			stmt.setString(1, ocorrencia.getStatus());
			stmt.setInt(2, historico.getCodigoOcorrencia());
			
			//Armazena o historico da solicitacao
			stmt.setString(3, historico.getDescricao());
			stmt.setString(4, historico.getUsuario());
			stmt.setInt(5, historico.getCodigoOcorrencia());
			stmt.setDate(6, new Date(historico.getDataHistorico().getTimeInMillis()));
			
			stmt.execute();
			stmt.close();
				
		}
		catch(SQLException e)
		{
			throw new RuntimeException(e);
		}
	}
			
	public List<Ocorrencia_Historico> getHistorico(int codigoIncidente)
	{
		// TODO Auto-generated method stub
		try
		{
			PreparedStatement stmt = this.connection.prepareStatement("SELECT * from incidentehistorico where codigoincidente=? order by id");
			
			stmt.setInt(1, codigoIncidente);
			
			ResultSet rs = stmt.executeQuery();
			List<Ocorrencia_Historico> historicoList = new ArrayList<Ocorrencia_Historico>();
			
			while(rs.next())
			{
				//Criando um nova instancia
				Ocorrencia_Historico historico = new Ocorrencia_Historico();
				
				//Montado o Calendar
				Calendar data = Calendar.getInstance();
				data.setTime(rs.getDate("data"));
				historico.setDataHistorico(data);
				
				historico.setDescricao(rs.getString("descricao"));
				historico.setUsuario(rs.getString("usuario"));
			
				//Adicionando objeto a lista
				historicoList.add(historico);
			}
					
			rs.close();
			stmt.close();
			return historicoList;
				
		}
		catch(SQLException e)
		{
			throw new RuntimeException(e);
		}
	}
		
	public void fecharIncidente(Ocorrencia ocorrencia, Ocorrencia_Historico historico)
	{
		try
		{
			String sql = "BEGIN;"
						 +"UPDATE incidente SET status=?, datafechamento=?, faq=? where id=?;"
						 +"INSERT INTO incidentehistorico(descricao,usuario,codigoincidente,data) VALUES(?,?,?,?);"
						 +"COMMIT;";
						 
			PreparedStatement stmt = this.connection.prepareStatement(sql);
			System.out.println("Faq: "+ocorrencia.getFaq());
			//Insere na tabela solicitacao
			stmt.setString(1, ocorrencia.getStatus());
			stmt.setDate(2, new Date(ocorrencia.getDataFechamento().getTimeInMillis()));
			stmt.setString(3, ocorrencia.getFaq());
			stmt.setInt(4, ocorrencia.getCodigo());
			
			//Armazena o historico da solicitacao
			stmt.setString(5, historico.getDescricao());
			stmt.setString(6, historico.getUsuario());
			stmt.setInt(7, ocorrencia.getCodigo());
			stmt.setDate(8, new Date(ocorrencia.getDataFechamento().getTimeInMillis()));
			
			stmt.execute();
			stmt.close();
						
		}
		
		catch(SQLException e)
		{
			throw new RuntimeException(e);
		}
		
	}

	public List<Ocorrencia> getFiltro(String[] status, Usuario usuario) {
		try
		{

			List<Ocorrencia> ocorrenciaList = new ArrayList<Ocorrencia>();
			
			for(String st : status)
			{
				PreparedStatement stmt;
				
				if(usuario.getGrupo().equalsIgnoreCase("ADMINISTRADORES"))
				{
					String sql ="SELECT id,categoria,unidade,local,cliente,operador,dataabertura," +
						    "datafechamento,prioridade,status from incidente " +
						    "WHERE status=? order by id desc";
					
					stmt = this.connection.prepareStatement(sql);
					stmt.setString(1, st);
				}
				
				else
				{
					if(verificaResponsavel(usuario) != 0)
					{
						String sql ="SELECT id,categoria,unidade,local,cliente,operador,dataabertura," +
							    "datafechamento,prioridade,status from incidente " +
							    "WHERE status=? and area IN("+ 
							   				"SELECT nome from area WHERE responsavel IN("+
							   												  "SELECT t2.nome from usuario as t1, responsavel as t2 "+
							   												  "WHERE t1.usuario=? and t1.idresponsavel=t2.id" +
							   												  ")" +
							   ") order by id desc";
						
						stmt = this.connection.prepareStatement(sql);
						
						stmt.setString(1, st);
						stmt.setString(2, usuario.getUsuario());
					}
					
					else
					{
						String sql ="SELECT id,categoria,unidade,local,cliente,operador,dataabertura," +
							    "datafechamento,prioridade,status from incidente " +
							    "WHERE status=? and area=? order by id desc";
						
						stmt = this.connection.prepareStatement(sql);
						
						stmt.setString(1, st);
						stmt.setString(2, usuario.getArea());
					}
					
					
				}

				ResultSet rs = stmt.executeQuery();
				
				while(rs.next())
				{
					//Criando um nova instancia
					Ocorrencia ocorrencia = new Ocorrencia();
					ocorrencia.setCodigo(rs.getInt("id"));
					ocorrencia.setCategoria(rs.getString("categoria"));
					ocorrencia.setUnidade(rs.getString("unidade"));
					ocorrencia.setLocal(rs.getString("local"));
					ocorrencia.setCliente(rs.getString("cliente"));
					ocorrencia.setOperador(rs.getString("operador"));
					
					//Montado o Calendar
					Calendar dataAbertura = Calendar.getInstance();
					Calendar dataFechamento = Calendar.getInstance();
					dataAbertura.setTime(rs.getDate("dataabertura"));
					ocorrencia.setDataAbertura(dataAbertura);
					
					if(rs.getDate("datafechamento") != null )
					{
						dataFechamento.setTime(rs.getDate("datafechamento"));
						ocorrencia.setDataFechamento(dataFechamento);
					}
					ocorrencia.setPrioridade(rs.getString("prioridade"));
					ocorrencia.setStatus(rs.getString("status"));
									
					//Adicionando objeto a lista
					ocorrenciaList.add(ocorrencia);

				}
			}


			Collections.sort(ocorrenciaList);
			return ocorrenciaList;
		}
		
		catch(SQLException e)
		{
			throw new RuntimeException(e);
		}
		
		
		
	}
	
	public List<Ocorrencia> getFiltro2(String[] status)
	{
		try
		{
			List<Ocorrencia> ocorrenciaList = new ArrayList<Ocorrencia>();
			for(String st : status)
			{
				
				String sql ="SELECT distinct status from incidente where status=?";
				
				PreparedStatement stmt = this.connection.prepareStatement(sql);
		
				stmt.setString(1, st);
				
				ResultSet rs = stmt.executeQuery();
				
				while(rs.next())
				{
					//Criando um nova instancia
					Ocorrencia ocorrencia = new Ocorrencia();
					ocorrencia.setStatus(rs.getString("status"));
					//Adicionando objeto a lista
					ocorrenciaList.add(ocorrencia);
				}
			}
			
			return ocorrenciaList;
		}
		
		catch(SQLException e)
		{
			throw new RuntimeException(e);
		}
	}		
}